package demoMod.anm2editor.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import demoMod.anm2editor.localization.LocalizedStrings;
import demoMod.anm2editor.model.Tuple3;
import demoMod.gdxform.core.FormManager;
import demoMod.gdxform.enums.GFrameWindowStyle;
import demoMod.gdxform.ui.*;

import java.util.ArrayList;
import java.util.List;

public class SinglePropertyAdjustWindow extends GFrame {
    private Tuple3<Float, Float, Float> floatFunc;
    private Tuple3<Integer, Integer, Float> intFunc;
    private Tuple3<Boolean, Boolean, Boolean> booleanFunc;
    private Runnable confirmCallback;

    public SinglePropertyAdjustWindow(BitmapFont bannerFont, Tuple3 func, FuncType funcType, String propertyName) {
        super(Gdx.graphics.getWidth() / 2.0F - Gdx.graphics.getWidth() * 0.125F, Gdx.graphics.getHeight() * 0.375F, Gdx.graphics.getWidth() * 0.25F, Gdx.graphics.getHeight() * 0.25F, bannerFont, GFrameWindowStyle.CLOSE_BUTTON_ONLY, false);
        switch (funcType) {
            case FLOAT:
                this.floatFunc = new Tuple3<>((float) func.item1, (float) func.item2, (float) func.item3);
                break;
            case INT:
                this.intFunc = new Tuple3<>((int) func.item1, (int) func.item2, (float) func.item3);
                break;
            case BOOLEAN:
                this.booleanFunc = new Tuple3<>((boolean) func.item1, (boolean) func.item2, (boolean) func.item3);
                break;
        }
        List<String> strings = LocalizedStrings.getStrings("SinglePropertyAdjustWindow");
        setTitle(String.format(strings.get(0), propertyName));
        switch (funcType) {
            case FLOAT:
            case INT:
                GLabel lBaseValue = new GLabel(getWidth() * 0.05F, getHeight() * 0.65F, getWidth(), getHeight() * 0.07F, bannerFont);
                lBaseValue.setText(strings.get(1));
                GLabel lBmValue = new GLabel(getWidth() * 0.4F, getHeight() * 0.65F, getWidth(), getHeight() * 0.07F, bannerFont);
                lBmValue.setText(strings.get(2));
                GLabel lPercent = new GLabel(getWidth() * 0.8F, getHeight() * 0.65F, getWidth(), getHeight() * 0.07F, bannerFont);
                lPercent.setText(strings.get(3));

                addElement(lBaseValue);
                addElement(lBmValue);
                addElement(lPercent);

                GTextField tBaseValue = new GTextField(getWidth() * 0.05F, getHeight() * 0.45F, getWidth() * 0.2F, getHeight() * 0.1F, bannerFont) {
                    @Override
                    public boolean keyDown(int keyCode) {
                        if (keyCode == Input.Keys.ENTER && FormManager.getInstance().getEventHooks().getCurrentFocusedElement() == this) {
                            FormManager.getInstance().getEventHooks().setCurrentFocusedElement(getParent());
                            return true;
                        }
                        return super.keyDown(keyCode);
                    }

                    @Override
                    public void deactivate() {
                        super.deactivate();
                        if (funcType == FuncType.FLOAT) {
                            floatFunc.item1 = Float.parseFloat(getText());
                        } else {
                            intFunc.item1 = Integer.parseInt(getText());
                        }
                    }
                };
                tBaseValue.setCharFilter(funcType == FuncType.FLOAT ? "[0-9.\\-]" : "[0-9\\-]");
                tBaseValue.setText(funcType == FuncType.FLOAT ? Float.toString((Float) func.item1) : Integer.toString((Integer) func.item1));

                GTextField tBmValue = new GTextField(getWidth() * 0.4F, getHeight() * 0.45F, getWidth() * 0.2F, getHeight() * 0.1F, bannerFont) {
                    @Override
                    public boolean keyDown(int keyCode) {
                        if (keyCode == Input.Keys.ENTER && FormManager.getInstance().getEventHooks().getCurrentFocusedElement() == this) {
                            FormManager.getInstance().getEventHooks().setCurrentFocusedElement(getParent());
                            return true;
                        }
                        return super.keyDown(keyCode);
                    }

                    @Override
                    public void deactivate() {
                        super.deactivate();
                        if (funcType == FuncType.FLOAT) {
                            floatFunc.item2 = Float.parseFloat(getText());
                        } else {
                            intFunc.item2 = Integer.parseInt(getText());
                        }
                    }
                };
                tBmValue.setCharFilter(funcType == FuncType.FLOAT ? "[0-9.\\-]" : "[0-9\\-]");
                tBmValue.setText(funcType == FuncType.FLOAT ? Float.toString((Float) func.item2) : Integer.toString((Integer) func.item2));

                GTextField tPercent = new GTextField(getWidth() * 0.8F, getHeight() * 0.45F, getWidth() * 0.2F, getHeight() * 0.1F, bannerFont) {
                    @Override
                    public boolean keyDown(int keyCode) {
                        if (keyCode == Input.Keys.ENTER && FormManager.getInstance().getEventHooks().getCurrentFocusedElement() == this) {
                            FormManager.getInstance().getEventHooks().setCurrentFocusedElement(getParent());
                            return true;
                        }
                        return super.keyDown(keyCode);
                    }

                    @Override
                    public void deactivate() {
                        super.deactivate();
                        floatFunc.item3 = Float.parseFloat(getText() == null ? "100.0" : getText());
                    }
                };
                tPercent.setCharFilter("[0-9.\\-]");
                tPercent.setText(Float.toString((Float) func.item3));

                addElement(tBaseValue);
                addElement(tBmValue);
                addElement(tPercent);
                break;
            case BOOLEAN:
                float y = getHeight() * 0.7F;
                List<String> options = new ArrayList<>();
                options.add(strings.get(4));
                options.add(strings.get(5));
                options.add(strings.get(6));
                options.add(strings.get(7));
                List<GRadioButton> buttonGroup = new ArrayList<>();
                for (String option : options) {
                    GRadioButton radioButton = new GRadioButton(20.0F, y, 12, 12, bannerFont) {
                        @Override
                        public void onClick() {
                            int index = buttonGroup.indexOf(this);
                            switch (index) {
                                case 0:
                                    booleanFunc.item1 = false;
                                    booleanFunc.item2 = false;
                                    booleanFunc.item3 = false;
                                    break;
                                case 1:
                                    booleanFunc.item1 = true;
                                    booleanFunc.item2 = false;
                                    booleanFunc.item3 = false;
                                    break;
                                case 2:
                                    booleanFunc.item1 = false;
                                    booleanFunc.item2 = true;
                                    booleanFunc.item3 = false;
                                    break;
                                case 3:
                                    booleanFunc.item1 = false;
                                    booleanFunc.item2 = false;
                                    booleanFunc.item3 = true;
                                    break;
                            }
                        }
                    };
                    radioButton.setText(option);
                    radioButton.setGroup(buttonGroup);
                    y -= 20;
                }
                for (GRadioButton radioButton : buttonGroup) {
                    addElement(radioButton);
                }
                if (!buttonGroup.isEmpty()) {
                    if (booleanFunc.item1) {
                        buttonGroup.get(0).setState(1);
                    }
                    if (booleanFunc.item2) {
                        buttonGroup.get(1).setState(1);
                    }
                    if (booleanFunc.item3) {
                        buttonGroup.get(2).setState(1);
                    }
                }
                break;
        }
        GButton confirm = new GButton(78, 4, 50, 20, bannerFont) {
            @Override
            public void onClick() {
                switch (funcType) {
                    case FLOAT:
                        func.item1 = floatFunc.item1;
                        func.item2 = floatFunc.item2;
                        func.item3 = floatFunc.item3;
                        break;
                    case INT:
                        func.item1 = intFunc.item1;
                        func.item2 = intFunc.item2;
                        func.item3 = intFunc.item3;
                        break;
                    case BOOLEAN:
                        func.item1 = booleanFunc.item1;
                        func.item2 = booleanFunc.item2;
                        func.item3 = booleanFunc.item3;
                        break;
                }
                if (confirmCallback != null) {
                    confirmCallback.run();
                }
                FormManager.getInstance().removeContainer(SinglePropertyAdjustWindow.this);
            }
        };
        confirm.setText(strings.get(8));
        confirm.setBackground(new Color(0, 47.0F / 255.0F, 147.0F / 255.0F, 1.0F));
        confirm.setBorderWidth(2);
        confirm.setBorder(Color.LIGHT_GRAY.cpy());
        GButton cancel = new GButton(138, 4, 50, 20, bannerFont) {
            @Override
            public void onClick() {
                FormManager.getInstance().removeContainer(SinglePropertyAdjustWindow.this);
            }
        };
        cancel.setText(strings.get(9));
        cancel.setBackground(Color.LIGHT_GRAY.cpy());
        cancel.setBorderWidth(2);
        cancel.setBorder(Color.LIGHT_GRAY.cpy());
        addElement(confirm);
        addElement(cancel);
    }

    public void setConfirmCallback(Runnable confirmCallback) {
        this.confirmCallback = confirmCallback;
    }

    enum FuncType {
        FLOAT,
        INT,
        BOOLEAN
    }
}
